/* Copyright 2009 Requirements Management System 
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.mags.remas.model.entity.provider;

// Generated Dec 6, 2009 5:47:57 PM by Hibernate Tools 3.2.2.GA
// powered by MAGS

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.mags.dao.common.ERestrictionOperator;
import org.mags.dao.common.IRestrictionBuilder;
import org.mags.dao.provider.NoCacheableDataProvider;
import org.mags.remas.model.entity.Entity;
import org.mags.remas.model.entity.EntityCategory;

public class EntityProvider extends NoCacheableDataProvider<Entity> {
	private static final long serialVersionUID = 1L;	
	private EntityTypeProvider entityTypeProvider;
	private EntityStatusProvider entityStatusProvider;
	private EntityCategoryProvider entityCategoryProvider;
	
	public List<Entity> getByEntityTypeId(int entityTypeId, String[][] orderBy, int firstRecord, int numRecords) {
		IRestrictionBuilder restrictionBuilder = super.getRestrictionBuilder();
		restrictionBuilder.addConditionAnd("entityType.entityTypeId", ERestrictionOperator.EQ, entityTypeId);
		return super.getByRestriction(null, restrictionBuilder, orderBy, firstRecord, numRecords);
	}
	private Map<Short, Entity> rootEntities= new HashMap<Short, Entity>();
	
	public EntityStatusProvider getEntityStatusProvider() {
		return entityStatusProvider;
	}
	public void setEntityStatusProvider(EntityStatusProvider entityStatusProvider) {
		this.entityStatusProvider = entityStatusProvider;
	}
	/**
	 * delete entities with no relationships
	 * this procedure is in gamma release due HIBERNATE IMPLEMENTATION bugs
	 * @return 
	 * size deleted entities
	 */
	public long deleteLonelyEntities(List<Integer> idEntityTypes, Entity root) {
		String sql="delete from Entity where entityId!=:rootId and entityId in (";
		sql = sql + "select entityId from Entity where entityId not in(select er.entity.entityId from EntityRelationship er) ";
		sql = sql + "and entityId not in(select er.entityParent.entityId from EntityRelationship er) ";
		if(idEntityTypes.size()>0) {
			String types = null;
			for(Integer id: idEntityTypes) {
				if(types==null)
					types=String.valueOf(id);
				else
					types = types + "," + String.valueOf(id);
			}
			sql = sql + " and entityType.entityTypeId in(" + types + ")";
		}
		sql = sql + ")";
		return super.executeUpdate(sql, new String[]{"rootId"}, new Object[]{root.getEntityId()});
	}
	private synchronized void loadRoot(short entityCategoryId) {
		Entity entity = rootEntities.get(entityCategoryId);
		if(entity==null) {
			EntityCategory entityCategory = entityCategoryProvider.getById(entityCategoryId);
			entity = getByCode("ROOT-"+entityCategory.getCode());
			rootEntities.put(entityCategoryId, entity);
		}	
	}
	public Entity getROOT(short entityCategoryId) {
		Entity entity = rootEntities.get(entityCategoryId);
		if(entity==null)
			loadRoot(entityCategoryId);
		entity = rootEntities.get(entityCategoryId);
		return entity;
	}
	public Entity getByCode(String code) {
		return super.getOneByField("code", code);
	}
	public EntityProvider(EntityTypeProvider entityTypeProvider, EntityStatusProvider entityStatusProvider, EntityCategoryProvider entityCategoryProvider) {
		this.entityTypeProvider = entityTypeProvider;
		this.entityStatusProvider = entityStatusProvider;
		this.entityCategoryProvider = entityCategoryProvider;
	}
	public EntityTypeProvider getEntityTypeProvider() {
		return entityTypeProvider;
	}
	public void setEntityTypeProvider(EntityTypeProvider entityTypeProvider) {
		this.entityTypeProvider = entityTypeProvider;
	}
	protected void loadProperties(Entity one) {
		one.setEntityType(entityTypeProvider.getById(one.getEntityType().getEntityTypeId()));
	}
}
